#include <iostream>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
//#include "1009.h"
using namespace std;

#define MAXNUM 100000
#define mydebug  

struct node {
    int n;
    int d;

    node(int num, int digit) : n(num), d(digit) {
    }

    node() {
        n = 0;
        d = 0;
    }
};



void imgRLE(node* nl, int index, int width, node* rl, int totalpixal);
void insertRLENode(node* nl, int& rindex, node newnode);
void printRLENode(node* nl, int rindex, int width);

int get_west(node* nl, int i, int imgloc, int j, int width);
int get_northwest(node* nl, int i, int imgloc, int j, int width);
int get_north(node* nl, int i, int imgloc, int j, int width);
int get_northeast(node* nl, int i, int imgloc, int j, int width);
int get_east(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum);
int get_southeast(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum);
int get_south(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum);
int get_southwest(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum);

int main() {
    node nl[MAXNUM];
    node rl[MAXNUM];
    int index;
    int col;
    cin >> col;
    int totalpixal;
    while (col != 0) {
        index = 0;
        totalpixal = 0;
        int num, dig;
        cin >> dig >> num;
        while (num != 0 || dig != 0) {
            totalpixal += num;
            node n(num, dig);
            nl[index++] = n;
            cin >> dig >> num;
        }
        assert(index < MAXNUM);
        imgRLE(nl, index, col, rl, totalpixal);
        cin >> col;
    }
    cout << "0" << endl;
    return 0;
}

void imgRLE(node* nl, int index, int width, node* rl, int totalpixal) {
    int rindex = 0;
    int imgloc = 0;
    int i = 0;
    int uu[8];
    node nnn;
    while (i < index) { //every time fetch a node until ends
        node n = nl[i];
        if (n.n < width * 2 + 3) {
            for (int j = 0; j < n.n; j++) {
                uu[0] = get_west(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[0]);
                uu[1] = get_northwest(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[1]);
                uu[2] = get_north(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[2]);
                uu[3] = get_northeast(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[3]);
                uu[4] = get_east(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[4]);
                uu[5] = get_southeast(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[5]);
                uu[6] = get_south(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[6]);
                uu[7] = get_southwest(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[7]);
                int largedis = 0;
                for (int k = 0; k < 8; k++) {
                    int dd = abs(n.d - uu[k]);
                    if (dd > largedis) {
                        largedis = dd;
                    }
                }
                nnn.n = 1;
                nnn.d = largedis;
                insertRLENode(rl, rindex, nnn);
            }
        } else {
            // larger than 2 columns
            // process the 1st column
            for (int j = 0; j < width + 1; j++) {
                uu[0] = get_west(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[0]);
                uu[1] = get_northwest(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[1]);
                uu[2] = get_north(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[2]);
                uu[3] = get_northeast(nl, i, imgloc, j, width);
                mydebug("%d \n", uu[3]);
                uu[4] = get_east(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[4]);
                uu[5] = get_southeast(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[5]);
                uu[6] = get_south(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[6]);
                uu[7] = get_southwest(nl, i, imgloc, j, width, index, totalpixal);
                mydebug("%d \n", uu[7]);
                int largedis = 0;
                for (int k = 0; k < 8; k++) {
                    int dd = abs(n.d - uu[k]);
                    if (dd > largedis) {
                        largedis = dd;
                    }
                }
                nnn.n = 1;
                nnn.d = largedis;
                insertRLENode(rl, rindex, nnn);
            }
            //process the middle part
            nnn.n = n.n - (width * 2 + 2);
            nnn.d = 0;
            insertRLENode(rl, rindex, nnn);
            //process the last part
            for (int j = width + 1; j > 0; j--) {
                int nnl = n.n - j;
                uu[0] = get_west(nl, i, imgloc, nnl, width);
                mydebug("%d \n", uu[0]);
                uu[1] = get_northwest(nl, i, imgloc, nnl, width);
                mydebug("%d \n", uu[1]);
                uu[2] = get_north(nl, i, imgloc, nnl, width);
                mydebug("%d \n", uu[2]);
                uu[3] = get_northeast(nl, i, imgloc, nnl, width);
                mydebug("%d \n", uu[3]);
                uu[4] = get_east(nl, i, imgloc, nnl, width, index, totalpixal);
                mydebug("%d \n", uu[4]);
                uu[5] = get_southeast(nl, i, imgloc, nnl, width, index, totalpixal);
                mydebug("%d \n", uu[5]);
                uu[6] = get_south(nl, i, imgloc, nnl, width, index, totalpixal);
                mydebug("%d \n", uu[6]);
                uu[7] = get_southwest(nl, i, imgloc, nnl, width, index, totalpixal);
                mydebug("%d \n", uu[7]);
                int largedis = 0;
                for (int k = 0; k < 8; k++) {
                    int dd = abs(n.d - uu[k]);
                    if (dd > largedis) {
                        largedis = dd;
                    }
                }
                nnn.n = 1;
                nnn.d = largedis;
                insertRLENode(rl, rindex, nnn);
            }
        }
        imgloc += n.n;
        i++;
    }
    printRLENode(rl, rindex, width);
}

void insertRLENode(node* nl, int& rindex, node newnode) {
    assert(rindex < MAXNUM);
    if (rindex == 0) {
        // new node
        nl[rindex++] = newnode;
    } else {
        if (nl[rindex - 1].d == newnode.d) {
            nl[rindex - 1].n += newnode.n;
        } else {
            nl[rindex++] = newnode;
        }
    }
}

void printRLENode(node* nl, int rindex, int width) {
    cout << width << endl;
    for (int i = 0; i < rindex; i++) {
        cout << nl[i].d << " " << nl[i].n << endl;
    }
    cout << "0 0" << endl;
}

/*
 * get the neighbor value for a pixcal
 *
 */
int get_west(node* nl, int i, int imgloc, int j, int width) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_west ", curloc);
    //    if (curloc % width == 0) {
    //        //if the first column of the row, return the same value;
    //        return nl[i].d;
    //    } else {
    if (j == 0 && curloc % width != 0) { // the first data in the rle format
        if (i == 0) {
            return nl[i].d;
        } else {
            return nl[i - 1].d;
        }
    }
    return nl[i].d;
    //    }
}

int get_northwest(node* nl, int i, int imgloc, int j, int width) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_northwest ", curloc);
    //    if (curloc % width == 0) {
    //        return nl[i].d;
    //    } else {
    if (curloc >= width && curloc % width != 0) {
        int k = j;
        int jj = 0;
        while (k < width + 1) {
            jj++;
            k += nl[i - jj].n;
        }
        return nl[i - jj].d;

    }
    return nl[i].d;
    //    }
}

int get_north(node* nl, int i, int imgloc, int j, int width) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_north ", curloc);
    if (curloc < width) {
        return nl[i].d;
    } else {
        int k = j;
        int jj = 0;
        while (k < width) {
            jj++;
            k += nl[i - jj].n;
        }
        return nl[i - jj].d;
    }
}

int get_northeast(node* nl, int i, int imgloc, int j, int width) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_northeast ", curloc);
    //    if (curloc % width == width - 1) {
    //        return nl[i].d;
    //    } else {
    if (curloc >= width && curloc % width != width - 1) {
        int k = j;
        int jj = 0;
        while (k < width - 1) {
            jj++;
            k += nl[i - jj].n;
        }
        return nl[i - jj].d;
    }
    return nl[i].d;
    //    }
}

int get_east(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_east ", curloc);
    //    if (curloc % width == width - 1) {
    //        return nl[i].d;
    //    } else {
    if (j == nl[i].n - 1 && curloc % width != width - 1) {
        if (i == maxindex - 1) {
            return nl[i].d;
        } else {
            return nl[i + 1].d;
        }
    }
    return nl[i].d;
    //    }
}

int get_southeast(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_southeast ", curloc);
    //    if (curloc % width == width - 1) {
    //        return nl[i].d;
    //    } else {
    if (curloc < maxnodenum - width && curloc % width != width - 1) {
        int k = nl[i].n - (j + 1);
        int jj = 0;
        while (k < width + 1) {
            jj++;
            k += nl[i + jj].n;
        }
        return nl[i + jj].d;

    }
    return nl[i].d;
    //    }
}

int get_south(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_south ", curloc);
    if (curloc >= maxnodenum - width) {
        return nl[i].d;
    } else {
        int k = nl[i].n - (j + 1);
        int jj = 0;
        while (k < width) {
            jj++;
            k += nl[i + jj].n;
        }
        return nl[i + jj].d;
    }
}

int get_southwest(node* nl, int i, int imgloc, int j, int width, int maxindex, int maxnodenum) {
    int curloc = imgloc + j;
    mydebug("current pixa index %d for get_southwest ", curloc);
    //    if (curloc % width == 0) {
    //        return nl[i].d;
    //    } else {
    if (curloc < maxnodenum - width && curloc % width != 0) {
        int k = nl[i].n - (j + 1);
        int jj = 0;
        while (k < width - 1) {
            jj++;
            k += nl[i + jj].n;
        }
        return nl[i + jj].d;

    }
    return nl[i].d;
    //    }
}
